package br.ufpe.cin.vspeed.gui;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.WindowConstants;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

/**
 * @author <a href="mailto:andreza.lba@gmail.com">Andreza Leite de Alencar</a>
 */
public class PanelJavadoc extends javax.swing.JPanel implements HyperlinkListener, ActionListener {
	private static final long serialVersionUID = -626702634774343873L;
	
	private JPanel jPanelMenu;
	private JButton jButtonHome;
	private JLabel urlLabel;
	private JTextField urlField;
	private JPanel topPanel;
	private JEditorPane htmlPane;
	private JScrollPane scrollPane;
	private JButton jButtonNext;
	private JButton jButtonPrevious;
	
	private final String initialURL;
	
	private String previousURL;
	private String nextURL;

	public PanelJavadoc() {
		super();
		URL resource = ClassLoader.getSystemClassLoader().getResource("doc/index.html");
		this.initialURL = resource.toExternalForm();
		initGUI();
	}

	private void initGUI() {
		GroupLayout thisLayout = new GroupLayout((JComponent)this);
		this.setLayout(thisLayout);
		this.setPreferredSize(new java.awt.Dimension(678, 380));
		{
			topPanel = new JPanel();
			topPanel.setBackground(Color.lightGray);
			{
				urlLabel = new JLabel();
				topPanel.add(urlLabel);
				urlLabel.setText("URL:");
			}
			{
				urlField = new JTextField();
				topPanel.add(urlField);
				urlField.setColumns(30);
				urlField.setText(initialURL);
				urlField.setEditable(false);
				urlField.setEnabled(false);
				urlField.setVisible(false);
				urlField.addActionListener(this);
			}
		}
		{
			jPanelMenu = new JPanel();
			{
				jButtonHome = new JButton();
				jPanelMenu.add(jButtonHome);
				jButtonHome.setText("Home");
				jButtonHome.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent event) {
						homeClicked(event);
					}
				});
			}
			{
				jButtonPrevious = new JButton();
				jPanelMenu.add(jButtonPrevious);
				jButtonPrevious.setText("Previous");
				jButtonPrevious.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent event) {
						previousClicked(event);
					}
				});
			}
			{
				jButtonNext = new JButton();
				jPanelMenu.add(jButtonNext);
				jButtonNext.setText("Next");
				jButtonNext.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent event) {
						nextClicked(event);
					}
				});
			}
		}
		{
			scrollPane = new JScrollPane();
			{
				try {
					htmlPane = new JEditorPane(initialURL);
					GroupLayout htmlPaneLayout = new GroupLayout((JComponent)htmlPane);
					scrollPane.setViewportView(htmlPane);
					htmlPane.setPage(new URL(initialURL));
					htmlPane.setEditable(false);
					htmlPane.setPreferredSize(new java.awt.Dimension(611, 245));
					htmlPane.setLayout(null);
					htmlPane.addHyperlinkListener(this);
					htmlPaneLayout.setVerticalGroup(htmlPaneLayout.createParallelGroup());
					htmlPaneLayout.setHorizontalGroup(htmlPaneLayout.createParallelGroup());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}
				thisLayout.setVerticalGroup(thisLayout.createSequentialGroup()
					.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 0, GroupLayout.PREFERRED_SIZE)
					.addComponent(topPanel, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
					.addComponent(jPanelMenu, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
					.addComponent(scrollPane, 0, 261, Short.MAX_VALUE)
					.addContainerGap(17, 17));
				thisLayout.setHorizontalGroup(thisLayout.createParallelGroup()
					.addComponent(topPanel, GroupLayout.Alignment.LEADING, 0, 678, Short.MAX_VALUE)
					.addGroup(thisLayout.createSequentialGroup()
					    .addGap(20)
					    .addGroup(thisLayout.createParallelGroup()
					        .addComponent(scrollPane, GroupLayout.Alignment.LEADING, 0, 632, Short.MAX_VALUE)
					        .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
					            .addGap(189)
					            .addComponent(jPanelMenu, 0, 296, Short.MAX_VALUE)
					            .addGap(0, 147, GroupLayout.PREFERRED_SIZE)))
					    .addContainerGap(26, 26)));
	}
	

	/**
	 * @param event
	 */
	private void homeClicked(MouseEvent event) {
		String url = initialURL;

		this.previousURL = this.urlField.getText();
		this.nextURL = this.urlField.getText();
		
		try {
			htmlPane.setPage(new URL(url));
			urlField.setText(url);
		} catch (final IOException ioe) {
			warnUser("Can't follow link to " + url + ": " + ioe);
		}
	}

	/**
	 * @param event
	 */
	private void previousClicked(MouseEvent event) {
		String url = this.previousURL;
		
		this.previousURL = this.urlField.getText();
		this.nextURL = this.urlField.getText();
		
		try {
			htmlPane.setPage(new URL(url));
			urlField.setText(url);
		} catch (final IOException ioe) {
			warnUser("Can't follow link to " + url + ": " + ioe);
		}
	}

	/**
	 * @param event
	 */
	private void nextClicked(MouseEvent event) {
		String url = this.previousURL;
		
		this.previousURL = this.urlField.getText();
		this.nextURL = this.urlField.getText();
		
		try {
			htmlPane.setPage(new URL(url));
			urlField.setText(url);
		} catch (final IOException ioe) {
			warnUser("Can't follow link to " + url + ": " + ioe);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(final ActionEvent event) {
		System.out.println("Browser.actionPerformed()");
		String url;
		if (event.getSource() == this.urlField) {
			url = this.urlField.getText();
		} else {
			// Clicked "home" button instead of entering URL
			url = this.initialURL;
		}
		try {
			this.htmlPane.setPage(new URL(url));
			this.urlField.setText(url);
		} catch (final IOException ioe) {
			warnUser("Can't follow link to " + url + ": " + ioe);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see javax.swing.event.HyperlinkListener#hyperlinkUpdate(javax.swing.event.HyperlinkEvent)
	 */
	@Override
	public void hyperlinkUpdate(final HyperlinkEvent event) {
		if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
			try {
				
				this.previousURL = this.urlField.getText();
				this.nextURL = event.getURL().toExternalForm();
				
				this.htmlPane.setPage(event.getURL());
				this.urlField.setText(event.getURL().toExternalForm());
			} catch (final IOException ioe) {
				warnUser("Can't follow link to " + event.getURL().toExternalForm() + ": " + ioe);
			}
		}
	}

	private void warnUser(final String message) {
		JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
	}

	/**
	 * @return Returns the previousURL.
	 */
	public String getPreviousURL() {
		return previousURL;
	}

	/**
	 * @return Returns the nextURL.
	 */
	public String getNextURL() {
		return nextURL;
	}

	/**
	 * Changes the value of previousURL as the parameter.
	 * 
	 * @param previousURL
	 */
	public void setPreviousURL(String previous) {
		this.previousURL = previous;
	}

	/**
	 * Changes the value of nextURL as the parameter.
	 * 
	 * @param nextURL
	 */
	public void setNextURL(String next) {
		this.nextURL = next;
	}	
	
	public static void main(String[] args) {
		final JFrame frameResultInfo = new JFrame();
		final PanelJavadoc panelResultInformation = new PanelJavadoc();
		frameResultInfo.getContentPane().add(panelResultInformation);
		frameResultInfo.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frameResultInfo.pack();
		frameResultInfo.setLocationRelativeTo(frameResultInfo.getRootPane());
		frameResultInfo.setVisible(true);
	}

}
